package com.yilin.platform.base_core.interceptor;


import com.yilin.platform.base_core.application.BaseCode;
import com.yilin.platform.base_core.application.ServiceUtil;
import com.yilin.platform.base_core.application.UserUtil;
import com.yilin.platform.base_core.commons.annotation.SafeVerify;
import com.yilin.platform.base_core.commons.annotation.SkipLoginVerify;
import com.yilin.platform.base_core.commons.annotation.UserTarget;
import com.yilin.platform.base_core.commons.utils.ArrayUtil;
import com.yilin.platform.base_core.commons.utils.JsonUtil;
import com.yilin.platform.base_core.commons.utils.constant.HttpConstant;
import com.yilin.platform.entity.enums.user.UserType;
import com.yilin.platform.entity.user.Account;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;

/**
 * 微服务内部鉴权控制器
 */
@Configuration
public class TokenInterceptor extends HandlerInterceptorAdapter {
    private Logger logger = LoggerFactory.getLogger(TokenInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if (!(handler instanceof HandlerMethod)) {
            logger.error("-----------------請求的链接地址不存在------------------");
            logger.error("-----------------"+request.getRequestURI()+"------------------");
            logger.error("-----------------"+request.getRequestURL()+"------------------");
            logger.error("----------------------------------------------");
            return responseErr(response, BaseCode.RES_NOT_EXIST, "请求的链接地址不存在");
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        String requestToken = request.getHeader(HttpConstant.TOKEN);
        String deviceId = request.getHeader(HttpConstant.DEVICE_ID);
        String mobile = request.getHeader(HttpConstant.MOBILE);
        String serviceSafeKey = request.getHeader(HttpConstant.SERVICE_SAFE_KEY);
        //#### 不登录安全校验，添加此自动跳过用户所有拦截，验证失败时必须验证登录
        if (requestToken == null && serviceSafeKey != null ) {
            Boolean success = ServiceUtil.verifyServiceSafeNotify(handlerMethod.getMethod().getName(), serviceSafeKey);
            if (success) return true;
        }
        //#### 进行用户鉴权监控
        SkipLoginVerify skipLoginVerify = handlerMethod.getMethodAnnotation(SkipLoginVerify.class);
        if (skipLoginVerify != null) return true;
        Account loginUser = UserUtil.getLoginUser(requestToken);
        if (loginUser == null) return responseErr(response, BaseCode.NO_LOGIN, "您的登录已失效，请重新登录！");
        if (loginUser.getUserState()== Account.UserState.disable){
            return responseErr(response, BaseCode.NO_LOGIN, "您的账户已被停用，联系您管理员获取原因并重新开启！");
        }
        if (mobile != null && (deviceId == null || !deviceId.equals(loginUser.getDeviceId()))) {
            return responseErr(response, BaseCode.NO_LOGIN, "您的设备异常，请您重新登录！");
        }
        //#### 用户类型拦截
        UserTarget userTarget = handlerMethod.getMethodAnnotation(UserTarget.class);
        if (userTarget != null && userTarget.value().length > 0) {
            List<UserType> userTypeList = Arrays.asList(userTarget.value());
            if (!userTypeList.contains(loginUser.getUserType())) {
                List<String> stringList = userTypeNameList(new ArrayList<>(userTypeList));
                return responseErr(response, BaseCode.USER_TYPE_ERR, "您不能访问该接口，该接口仅支持：" + String.join(",", stringList + " 访问"));
            }
        }
        //#### 安全验证
        SafeVerify safeInterceptor = handlerMethod.getMethodAnnotation(SafeVerify.class);
        if (safeInterceptor != null) {
            String passCode = request.getParameter("safePassCode");
            Boolean success = UserUtil.verifyPassCode(loginUser, passCode);
            if (!success) return responseErr(response, BaseCode.SAFE_VERIFY_FAIL, "安全密码验证失败");
        }
        return true;
    }


    //返回前台数据
    private boolean responseErr(HttpServletResponse response, Integer code, String msg) {
        try {
            Map<String, Object> returnData = new HashMap<>();
            response.setCharacterEncoding("UTF-8");//设置字符集为'UTF-8'
            response.setContentType("application/json");//设置格式为text/json 
            returnData.put(HttpConstant.SUCCESS, false);
            returnData.put(HttpConstant.MSG, msg);
            returnData.put(HttpConstant.CODE, code);
            PrintWriter write = response.getWriter();
            write.write(JsonUtil.objectToJson(returnData));
            write.flush();
            write.close();
            return false;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    // 返回类型名称列表
    private List<String> userTypeNameList(List<UserType> userTypes) {
        return ArrayUtil.fieldAdd(userTypes, obj -> obj.name);
    }



}
